package com.imchenio.utils.parallel.ring;

import org.springframework.util.StringUtils;

import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

/**
 * 一致性Hash实现
 */
public class HashRing implements HashAlgorithm {

    protected SortedSet<Integer> ring;

    public HashRing(Set<String> initialNodes) {
        ring = new TreeSet<>();
        ring.add(0);
        for (String initialNode : initialNodes) {
            int result = map(initialNode);
            ring.add(result);
        }
    }

    @Override
    public int map(String randomString) {
        if (StringUtils.isEmpty(randomString)) {
            return -1;
        }
        final int p = 16777619;
        int result = (int) 2166136261L;
        for (int i = 0; i < randomString.length(); i++) {
            result = (result ^ randomString.charAt(i)) * p;
        }
        result += result << 13;
        result ^= result >> 7;
        result += result << 3;
        result ^= result >> 17;
        result += result << 5;

        return Math.abs(result);
    }

    @Override
    public int select(String randomString) {
        if (StringUtils.isEmpty(randomString)) {
            return -1;
        }
        int result = map(randomString);
        int lastRing = 0;
        for (int ringNode : ring) {
            if (result < ringNode) {
                return lastRing;
            }
            lastRing = ringNode;
        }
        return 0;
    }

}
